#ifndef __LIST_H__
#define __LIST_H__

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdio.h>

#define CLIST_OK 0
#define CLIST_ERR 1
#define CLIST_ERR_MEM 2
#define CLIST_ERR_PTR_NULL 3
#define CLIST_ERR_OPERATION 4
#define CLIST_ERR_NULL -1

#ifndef CLIST_CHECK_PTR_NULL
#define CLIST_CHECK_PTR_NULL(p)    \
    if (!p)                        \
    {                              \
        return CLIST_ERR_PTR_NULL; \
    }
#endif

typedef struct note_t Node;
typedef struct list_t List;
typedef struct clist_hooks_t clist_hooks_register_t;
typedef struct clist_mem_hooks_t clist_platform_hooks_t;

typedef void (*p_free)(void *data);
typedef void *(*p_malloc)(size_t size);
typedef int (*p_traverse)(void *nodeData, void *data);

struct note_t
{
    void *data;
    Node *next;
};

/* 定义不同平台的内存管理接口，未定义则使用默认的 */
struct clist_mem_hooks_t
{
    p_malloc pfun_malloc;
    p_free pfun_free;
};

struct clist_hooks_t
{
    p_free pfun_user_free;   //用户数据释放
    p_traverse pfun_compare; //比较节点的data参数是否相等，相等返回0
};

struct list_t
{
    Node *head;                   //头结点
    Node *tail;                   //尾结点
    int size;                     //链表大小
    clist_hooks_register_t hooks; //不同类型链表的钩子函数
};

List *clist_new_list(void);

int clist_platform_hook_reg(clist_platform_hooks_t *hooks);

int clist_hooks_reg(List *plist, clist_hooks_register_t *hooks);

int clist_delete_list(List *plist);

Node *clist_create_node(void *data, size_t size);

int clist_delete_node(Node *pnode, p_free pfun_user_free);

int clist_add_node(List *plist, Node *pnode);

int clist_add_node_by_data(List *plist, void *data, size_t size);

int clist_remove_node(List *plist);

int clist_remove_node_by_data(List *plist, void *data, p_traverse pfun_traverse);

int clist_traverse_list(List *plist, void *data, p_traverse pfun_traverse);

Node *clist_get_node_by_index(List *plist, int index);

Node *clist_find_node_by_data(List *plist, void *data, p_traverse pfun_traverse);

int clist_get_index_by_data(List *plist, void *data);

#ifdef __cplusplus
}
#endif

#endif /* __LIST_H__ */
